package ec.linde.modulos.proyectos;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import org.primefaces.component.datatable.DataTable;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

import ec.linde.enumeraciones.Estado;
import ec.linde.modulos.proyectos.servicio.ServicioPlanillaCliente;
import ec.linde.modulos.proyectos.servicio.ServicioRdo;
import ec.linde.persistencia.entidades.proyectos.DetallePlanillaCliente;
import ec.linde.persistencia.entidades.proyectos.DetalleRdo;
import ec.linde.persistencia.entidades.proyectos.PlanillaCliente;
import ec.linde.persistencia.entidades.proyectos.Rdo;

/**
 * TODO: Agregar descripcion
 * 
 * @FechaCreacion: 29/03/2013
 * @author: Alex Carrillo
 * @FechaModificacion: 29/03/2013
 * @author: Alex Carrillo
 * @version: 1.0
 */
@ManagedBean
@ViewScoped
public class PlanillaClienteBean extends PageController {

	private static final long serialVersionUID = 1L;

	/**
	 * Servicios
	 */
	@EJB
	private ServicioPlanillaCliente servicioPlanillaCliente;
	@EJB
	private ServicioRdo servicioRdo;

	/**
	 * Atributos Forma
	 */
	private PlanillaCliente planillaCliente;
	private DetallePlanillaCliente detallePlanillaClienteSeleccionado;
	private Integer idRdo;

	/**
	 * Listados 1. Lista Lazy DataModel 2. Lista Detalles 3. Listas Combo
	 */
	private LazyDataModel<PlanillaCliente> listaPlanillaCliente;
	private List<DetallePlanillaCliente> listaDetallePlanillaCliente;
	/**
	 * UI
	 */
	private DataTable dtPlanillaCliente;
	private DataTable dtDetallePlanillaCliente;
	private DataTable dtCronogramaPlanillaCliente;

	/**
	 * PostContrutor
	 */
	@PostConstruct
	public void init() {

		listaPlanillaCliente = new LazyDataModel<PlanillaCliente>() {

			private static final long serialVersionUID = 1L;

			@Override
			public List<PlanillaCliente> load(int startIndex, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
				List<PlanillaCliente> lista = new ArrayList<PlanillaCliente>();

				boolean ordenar = sortOrder == SortOrder.ASCENDING ? true : false;
				lista = servicioPlanillaCliente.obtenerListaPorPagina(startIndex, pageSize, sortField, ordenar, filters);

				listaPlanillaCliente.setRowCount(servicioPlanillaCliente.contarPorCriterio(filters));

				return lista;
			}
		};

	}

	/**
	 * Metodos
	 */

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#editar()
	 */
	public String editar() {
		addInfoMessage("Accion no permitida");
		return "";
	}

	/*
	 * (non-Javadoc)\
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#guardar()
	 */
	public String guardar() {
		try {
			if (validar()) {
				servicioPlanillaCliente.guardar(planillaCliente);
				addInfoMessage("Registro Guardado Correctamente");
				setEditado(false);
				limpiar();
				return "planillaCliente.xhtml?faces-redirect=true";
			} else {
				return "";
			}
		} catch (Exception e) {
			addErrorMessage("Error al Guardar el registro");
		}
		return "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#eliminar()
	 */
	public String eliminar() {
		return "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#limpiar()
	 */
	@Override
	public String limpiar() {
		planillaCliente = null;
		return "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ec.linde.modulos.proyectos.PageController#cancelar()
	 */
	@Override
	public String cancelar() {
		setEditado(false);
		limpiar();
		return "planillaCliente.xhtml?faces-redirect=true";
	}

	/**
	 * TODO: Agregar descripcion del metodo
	 * 
	 * @return
	 */
	public List<DetallePlanillaCliente> getListaDetallePlanillaCliente() {
		if (listaDetallePlanillaCliente == null) {
			listaDetallePlanillaCliente = new ArrayList<DetallePlanillaCliente>();
			for (DetallePlanillaCliente detallePlanillaCliente : planillaCliente.getListaDetallePlanillaCliente()) {
				if (!detallePlanillaCliente.isEliminado()) {
					listaDetallePlanillaCliente.add(detallePlanillaCliente);
				}
			}
		}
		return listaDetallePlanillaCliente;
	}

	/**
	 * Carga el plan operativo ya sea desde el proyecto o desde el ultimo plan operativo
	 */
	public void cargarPlanillaClienteDesdeRdo() {

		if (idRdo != null && this.planillaCliente == null) {

			// Cargo el detalle del Plan Operativo Actual
			Rdo rdo = servicioRdo.cargarDetalle(idRdo);

			// Cargo el plan operativo
			HashMap<String, String> filters = new HashMap<String, String>();
			filters.put("rdo.idRdo", "" + rdo.getId());
			List<PlanillaCliente> lista = servicioPlanillaCliente.obtenerListaCombo("", true, filters);

			// Si la lista del planillaCliente no existe me crea un nuevo planillaCliente
			if (lista.isEmpty()) {

				this.planillaCliente = new PlanillaCliente();
				planillaCliente.setRdo(rdo);
				planillaCliente.setEstado(Estado.ELABORADO);
				planillaCliente.setFecha(new Date());
				for (DetalleRdo drdo : rdo.getListaDetalleRdo()) {

					DetallePlanillaCliente dplanillaCliente = new DetallePlanillaCliente();
					dplanillaCliente.setIdDetallePlanillaCliente(0);
					dplanillaCliente.setPlanillaCliente(planillaCliente);
					dplanillaCliente.setPartida(drdo.getPartida());
					dplanillaCliente.setConcepto(drdo.getConcepto());
					dplanillaCliente.setCantidad(drdo.getCantidad());
					planillaCliente.getListaDetallePlanillaCliente().add(dplanillaCliente);

				}

			} else {

				if (lista.get(0).getEstado() == Estado.ELABORADO) {

					// Cargo el detalle del PlanillaCliente Actual y seto el plan operativo asl planillaCliente
					planillaCliente = servicioPlanillaCliente.cargarDetalle(lista.get(0).getId());
					planillaCliente.setRdo(rdo);

					// Se llena el hasmap de los detalles del planillaCliente actual y se eliminan
					HashMap<String, DetallePlanillaCliente> hmDPlanillaCliente = new HashMap<String, DetallePlanillaCliente>();
					for (DetallePlanillaCliente detallePlanillaCliente : planillaCliente.getListaDetallePlanillaCliente()) {
						hmDPlanillaCliente.put(detallePlanillaCliente.getPartida().getPadeId() + "~"
								+ detallePlanillaCliente.getConcepto().getConcId(), detallePlanillaCliente);
						detallePlanillaCliente.setEliminado(true);
					}

					// Se recorre el detalle del plan operativo para habilitar los registros que estan en el plan operativo y dar el orden al
					// planillaCliente del plan
					// operativo
					for (DetalleRdo drdo : rdo.getListaDetalleRdo()) {

						// Verifica si existe el detalle del planillaCliente y si existe lo activa caso contrario lo crea
						DetallePlanillaCliente detallePlanillaCliente = hmDPlanillaCliente.get(drdo.getPartida().getPadeId() + "~"
								+ drdo.getConcepto().getConcId());
						if (detallePlanillaCliente != null) {
							detallePlanillaCliente.setEliminado(false);
						} else {
							detallePlanillaCliente = new DetallePlanillaCliente();
							planillaCliente.getListaDetallePlanillaCliente().add(detallePlanillaCliente);
						}
						detallePlanillaCliente.setPlanillaCliente(planillaCliente);
						detallePlanillaCliente.setConcepto(drdo.getConcepto());
						detallePlanillaCliente.setCantidad(drdo.getCantidad());
						detallePlanillaCliente.setCantidadAnterior(servicioPlanillaCliente.cantidadPlanillaAnterior(rdo, drdo.getPartida(),
								drdo.getConcepto()));
					}

				} else {

					this.planillaCliente = new PlanillaCliente();
					planillaCliente.setRdo(rdo);
					planillaCliente.setEstado(Estado.ELABORADO);
					planillaCliente.setFecha(new Date());

					for (DetalleRdo drdo : rdo.getListaDetalleRdo()) {

						DetallePlanillaCliente dplanillaCliente = new DetallePlanillaCliente();
						dplanillaCliente.setIdDetallePlanillaCliente(0);
						dplanillaCliente.setPlanillaCliente(planillaCliente);
						dplanillaCliente.setPartida(drdo.getPartida());
						dplanillaCliente.setConcepto(drdo.getConcepto());
						dplanillaCliente.setCantidad(drdo.getCantidad());
						dplanillaCliente.setCantidadAnterior(servicioPlanillaCliente.cantidadPlanillaAnterior(rdo, drdo.getPartida(),
								drdo.getConcepto()));
						planillaCliente.getListaDetallePlanillaCliente().add(dplanillaCliente);

					}

				}
			}
			totalizar();
			setEditado(true);
		}

	}

	/**
	 * Aprueba el plan operativo
	 */
	public void aprobar() {
		if (planillaCliente != null) {
			if (planillaCliente.getEstado() == Estado.ELABORADO) {

				if (validarAprobacion(planillaCliente)) {
					servicioPlanillaCliente.cambiarEstado(planillaCliente.getId(), Estado.APROBADO);
					addInfoMessage("El registro se ha aprobado correctamente");
				}

			} else {
				addInfoMessage("Solo los planos operativos elaborados pueden ser aprobados");
			}

		} else {
			addInfoMessage("Seleccione un Registro");
		}

	}

	private boolean validarAprobacion(PlanillaCliente planillaCliente) {
		return false;
	}

	/**
	 * Totaliza los valores del plan operativo
	 */
	public void totalizar() {
		servicioPlanillaCliente.totalizar(planillaCliente);
	}

	/**
	 * VAlida el plan opertaivo antes de guardar
	 * 
	 * @return
	 */
	private boolean validar() {
		boolean resultado = true;
		return resultado;
	}

	/**
	 * Metodos Eventos
	 */

	/**
	 * Metodos GET Y SET
	 */

	/**
	 * Get del atributo planillaCliente
	 * 
	 * @return el valor del atributo planillaCliente
	 */
	public PlanillaCliente getPlanillaCliente() {
		return planillaCliente;
	}

	/**
	 * Set del atributo planillaCliente
	 * 
	 * @param proyecto
	 *            valor para asignar al atributo planillaCliente
	 */
	public void setPlanillaCliente(PlanillaCliente planillaCliente) {
		this.planillaCliente = planillaCliente;
	}

	/**
	 * Get del atributo idRdo
	 * 
	 * @return el valor del atributo idRdo
	 */
	public Integer getIdRdo() {
		return idRdo;
	}

	/**
	 * Set del atributo idRdo
	 * 
	 * @param idRdo
	 *            valor para asignar al atributo idRdo
	 */
	public void setIdRdo(Integer idRdo) {
		this.idRdo = idRdo;
	}

	public DetallePlanillaCliente getDetallePlanillaClienteSeleccionado() {
		return detallePlanillaClienteSeleccionado;
	}

	public void setDetallePlanillaClienteSeleccionado(DetallePlanillaCliente detallePlanillaClienteSeleccionado) {
		this.detallePlanillaClienteSeleccionado = detallePlanillaClienteSeleccionado;
	}

	public LazyDataModel<PlanillaCliente> getListaPlanillaCliente() {
		return listaPlanillaCliente;
	}

	public void setListaPlanillaCliente(LazyDataModel<PlanillaCliente> listaPlanillaCliente) {
		this.listaPlanillaCliente = listaPlanillaCliente;
	}

	public DataTable getDtPlanillaCliente() {
		return dtPlanillaCliente;
	}

	public void setDtPlanillaCliente(DataTable dtPlanillaCliente) {
		this.dtPlanillaCliente = dtPlanillaCliente;
	}

	/**
	 * Get del atributo dtCronogramaPlanillaCliente
	 * 
	 * @return el valor del atributo dtCronogramaPlanillaCliente
	 */
	public DataTable getDtCronogramaPlanillaCliente() {
		return dtCronogramaPlanillaCliente;
	}

	/**
	 * Set del atributo dtCronogramaPlanillaCliente
	 * 
	 * @param dtCronogramaPlanillaCliente
	 *            valor para asignar al atributo dtCronogramaPlanillaCliente
	 */
	public void setDtCronogramaPlanillaCliente(DataTable dtCronogramaPlanillaCliente) {
		this.dtCronogramaPlanillaCliente = dtCronogramaPlanillaCliente;
	}

	/**
	 * Get del atributo dtDetallePlanillaCliente
	 * 
	 * @return el valor del atributo dtDetallePlanillaCliente
	 */
	public DataTable getDtDetallePlanillaCliente() {
		return dtDetallePlanillaCliente;
	}

	/**
	 * Set del atributo dtDetallePlanillaCliente
	 * 
	 * @param dtDetallePlanillaCliente
	 *            valor para asignar al atributo dtDetallePlanillaCliente
	 */
	public void setDtDetallePlanillaCliente(DataTable dtDetallePlanillaCliente) {
		this.dtDetallePlanillaCliente = dtDetallePlanillaCliente;
	}

}
